﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Microsoft.VisualStudio.ArchitectureTools.CodeRepositoryQuery;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Powersource_UnitTests.TestBootstrappers;
using PowersourceUIToolkit;
using UCL.Powersource;
using UCL.Powersource.Mock;
using UCL.Powersource.TFS;
using UCL.Powersource.ViewModels;

namespace Powersource_UnitTests
{
    [TestClass]
    public class ViewModelActivation
    {
        bool WithPreview = true;
        Window wnd;
        DummyPowersourceBootStrapper bs;
        PowersourceMainViewModel MainVM;
        ReportingViewModel ReportingVM;
        SettingsViewModel SettingsVM;
        ContentControlConductor CCConductor;
        IPowersourceExt IPowersourceExt;

        //List<Assembly> Assemblies;

        [TestInitialize]
        public void StartUp()
        {

            bs = BootStrapperLoader.CreateDummyVisualStudio_RealStatMan_RealRepMan_RealTFS_DummyBridge();
            wnd = null;
            if (WithPreview)
            {
                wnd = new Window();
                wnd.Width = 500;
                wnd.Height = 400;
                wnd.ShowInTaskbar = true;
                wnd.Show();
            }
            MainVM = ViewModelLocator.GetViewModel<PowersourceMainViewModel>();
            ReportingVM = ViewModelLocator.GetViewModel<ReportingViewModel>();
            SettingsVM = ViewModelLocator.GetViewModel<SettingsViewModel>();
            CCConductor = new ContentControlConductor(wnd);
            CCConductor.Initialize();
            IPowersourceExt = PowersourceConnector.GetExtensibilityPoint();
            //MainVM.ConnectToTFS(bs.IVsEnv.TeamFoundationServerExt.);
        }

        [TestCleanup]
        public void Clean()
        {
            wnd.Close();
            MainVM = null;
            ReportingVM = null;
            SettingsVM = null;
            bs.Dispose();
        }


        [TestMethod]
        public void OpenReporting()
        {
            CCConductor.ActivateViewModel(MainVM);
            MainVM.StartUpTFSConnect();
            Assert.IsTrue(MainVM.IsTFSConnected, "Connection failed!");
            MainVM.OpenReporting();
            DoEvents();
            Assert.IsFalse(MainVM.IsActivated, "Main view not deactivated!");
            Assert.IsTrue(ReportingVM.IsActivated, "Reporting view not active!");
            ReportingVM.BackToMain();
            DoEvents();
            Assert.IsTrue(!ReportingVM.IsActivated, "Reporting view not deactivated!");
        }

        [TestMethod]
        public void OpenSettings()
        {
            CCConductor.ActivateViewModel(MainVM);
            MainVM.OpenSettings();
            DoEvents();
            Assert.IsFalse(MainVM.IsActivated, "Main view not deactivated!");
            Assert.IsTrue(SettingsVM.IsActivated, "Settings view not active!");
            SettingsVM.Exit();
            DoEvents();
            Assert.IsTrue(!SettingsVM.IsActivated, "Settings view not deactivated!");
        }

        [TestMethod]
        public void ApplicationStressTest()
        {
            CCConductor.ActivateViewModel(MainVM);
            for (int i = 0; i < 100; i++)
            {
                MainVM.OpenSettings();
                DoEvents(); 
                SettingsVM.Exit();
                DoEvents();
                MainVM.OpenReporting();
                DoEvents();
                ReportingVM.BackToMain();
                DoEvents();
            }
            Assert.IsTrue(MainVM.IsActivated, "Stress test failed!");
        }

        void DoEvents()
        {
            DispatcherFrame f = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
            (SendOrPostCallback)delegate(object arg)
            {
                DispatcherFrame fr = arg as DispatcherFrame;
                fr.Continue = false;
            }, f);
            Dispatcher.PushFrame(f);
        }
    }
}